package com.pkk.penguin.frame.know.java.driven.ext.beanfactorypostprocess.handle;

import com.pkk.penguin.frame.know.java.driven.ext.beanfactorypostprocess.bean.Blue;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;

/**
 * 自定义的bean工厂定制类
 *
 * @author peikunkun
 * @version V1.0
 * @date 2020-11-13 18:00
 **/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {

  /**
   * Modify the application context's internal bean definition registry after its
   * standard initialization. All regular bean definitions will have been loaded,
   * but no beans will have been instantiated yet. This allows for adding further
   * bean definitions before the next post-processing phase kicks in.
   *
   * @param registry the bean definition registry used by the application context
   * @throws BeansException in case of errors
   */
  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    System.out.println("postProcessBeanDefinitionRegistry is Running");

    final AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Blue.class)
        .addPropertyValue("name", "kunzai")
        .addConstructorArgValue("kunzai一号").getBeanDefinition();
    registry.registerBeanDefinition("kunzaiName", beanDefinition);
    System.out.println("刚注册的会包含吗?" + registry.containsBeanDefinition("kunzaiName"));
  }

  /**
   * Modify the application context's internal bean factory after its standard
   * initialization. All bean definitions will have been loaded, but no beans
   * will have been instantiated yet. This allows for overriding or adding
   * properties even to eager-initializing beans.
   *
   * @param beanFactory the bean factory used by the application context
   * @throws BeansException in case of errors
   */
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    System.out.println("postProcessBeanFactory is Running");
  }

  /**
   * Get the order value of this object.
   * <p>Higher values are interpreted as lower priority. As a consequence,
   * the object with the lowest value has the highest priority (somewhat
   * analogous to Servlet {@code load-on-startup} values).
   * <p>Same order values will result in arbitrary sort positions for the
   * affected objects.
   *
   * @return the order value
   * @see #HIGHEST_PRECEDENCE
   * @see #LOWEST_PRECEDENCE
   */
  @Override
  public int getOrder() {
    return HIGHEST_PRECEDENCE;
  }
}
